#include <gtk/gtk.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <stdio.h>

GtkTextBuffer *buffer;
double a,b;
char action;
int flag;

void calc_print(char *c)
{
	gchar *ret;
	GtkTextIter start,end;
	gtk_text_buffer_get_start_iter(buffer, &start);
	gtk_text_buffer_get_end_iter(buffer, &end);
	ret = gtk_text_buffer_get_text(buffer, &start, &end,TRUE);
	ret = strcat(ret, c);
	if(strlen(ret)<=32)
	{
		/* g_printf("%s\n",ret); */
		gtk_text_buffer_set_text(buffer, ret, -1);
	}
}

void calc_execute(double *x, char ex)
{
	GtkTextIter start,end;
	if((ex=='+')||(ex=='-')||(ex=='*')||(ex=='/')||(ex=='^')) action = ex;
	gtk_text_buffer_get_start_iter(buffer, &start);
	gtk_text_buffer_get_end_iter(buffer, &end);
	*x = atof(gtk_text_buffer_get_text(buffer, &start, &end,TRUE));
	gtk_text_buffer_set_text(buffer, " \0", -1);
}

void calc_clear()
{
	if(flag) gtk_text_buffer_set_text(buffer, " \0", -1);
	flag=0;
}

static void one_click(GtkWidget *widget, gpointer data)
{
	calc_clear();
	calc_print("1");
}
static void two_click(GtkWidget *widget, gpointer data)
{
	calc_clear();
	calc_print("2");
}
static void three_click(GtkWidget *widget, gpointer data)
{
	calc_clear();
	calc_print("3");
}
static void four_click(GtkWidget *widget, gpointer data)
{
	calc_clear();
	calc_print("4");
}
static void five_click(GtkWidget *widget, gpointer data)
{
	calc_clear();
	calc_print("5");
}
static void six_click(GtkWidget *widget, gpointer data)
{
	calc_clear();
	calc_print("6");
}
static void seven_click(GtkWidget *widget, gpointer data)
{
	calc_clear();
	calc_print("7");
}
static void eight_click(GtkWidget *widget, gpointer data)
{
	calc_clear();
	calc_print("8");
}
static void nine_click(GtkWidget *widget, gpointer data)
{
	calc_clear();
	calc_print("9");
}
static void zero_click(GtkWidget *widget, gpointer data)
{
	calc_clear();
	calc_print("0");
}

static void plus_click(GtkWidget *widget, gpointer data)
{
	calc_execute(&a,'+');
}

static void minus_click(GtkWidget *widget, gpointer data)
{
	calc_execute(&a, '-');
}

static void devide_click(GtkWidget *widget, gpointer data)
{
	calc_execute(&a, '/');
}

static void multi_click(GtkWidget *widget, gpointer data)
{
	calc_execute(&a, '*');
}

static void pow_click(GtkWidget *widget, gpointer data)
{
	calc_execute(&a, '^');
}

static void equal_click(GtkWidget *widget, gpointer data)
{
	gchar *ret;
	calc_execute(&b, '=');
	switch(action)
	{
		case('+'):
			asprintf(&ret,"%f\0",a+b);
			break;
		case('-'):
			asprintf(&ret,"%f\0",a-b);
			break;
		case('/'):
			asprintf(&ret,"%f\0",a/b);
			break;
		case('*'):
			asprintf(&ret,"%f\0",a*b);
			break;
		case('^'):
			asprintf(&ret,"%f\0",pow(a,b));
			break;
		case('q'):
			asprintf(&ret,"%f\0",sqrt(a));
			break;
	}
	gtk_text_buffer_set_text(buffer, ret, -1);
	flag=1;
}
int main (int   argc, char *argv[]) {
  GtkBuilder *builder;
  GtkWidget *window;
  GObject *button;
  GtkTextView *text_view;

  gtk_init (&argc, &argv);

  a=0;
  b=0;
  flag=0;
  /* Construct a GtkBuilder instance and load our UI description */
  builder = gtk_builder_new ();
  gtk_builder_add_from_file (builder, "layout.glade", NULL);

  /* Connect signal handlers to the constructed widgets. */
  window =(GtkWidget *) gtk_builder_get_object (builder, "frm_main");
  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);

  button = gtk_builder_get_object (builder, "cmd_one");
  g_signal_connect (button, "clicked", G_CALLBACK (one_click), NULL);

  button = gtk_builder_get_object (builder, "cmd_two");
  g_signal_connect (button, "clicked", G_CALLBACK (two_click), NULL);

  button = gtk_builder_get_object (builder, "cmd_three");
  g_signal_connect (button, "clicked", G_CALLBACK (three_click), NULL);

  button = gtk_builder_get_object (builder, "cmd_four");
  g_signal_connect (button, "clicked", G_CALLBACK (four_click), NULL);

  button = gtk_builder_get_object (builder, "cmd_five");
  g_signal_connect (button, "clicked", G_CALLBACK (five_click), NULL);

  button = gtk_builder_get_object (builder, "cmd_six");
  g_signal_connect (button, "clicked", G_CALLBACK (six_click), NULL);
  
  button = gtk_builder_get_object (builder, "cmd_seven");
  g_signal_connect (button, "clicked", G_CALLBACK (seven_click), NULL);

  button = gtk_builder_get_object (builder, "cmd_eight");
  g_signal_connect (button, "clicked", G_CALLBACK (eight_click), NULL);

  button = gtk_builder_get_object (builder, "cmd_nine");
  g_signal_connect (button, "clicked", G_CALLBACK (nine_click), NULL);

  button = gtk_builder_get_object (builder, "cmd_zero");
  g_signal_connect (button, "clicked", G_CALLBACK (zero_click), NULL);

  button = gtk_builder_get_object (builder, "cmd_plus");
  g_signal_connect (button, "clicked", G_CALLBACK (plus_click), NULL);

  button = gtk_builder_get_object (builder, "cmd_root");
  g_signal_connect (button, "clicked", G_CALLBACK (equal_click), NULL);

  button = gtk_builder_get_object (builder, "cmd_minus");
  g_signal_connect (button, "clicked", G_CALLBACK (minus_click), NULL);
  button = gtk_builder_get_object (builder, "cmd_multi");
  g_signal_connect (button, "clicked", G_CALLBACK (multi_click), NULL);
  button = gtk_builder_get_object (builder, "cmd_devide");
  g_signal_connect (button, "clicked", G_CALLBACK (devide_click), NULL);
  button = gtk_builder_get_object (builder, "cmd_pow");
  g_signal_connect (button, "clicked", G_CALLBACK (pow_click), NULL);

  text_view = (GtkTextView *) gtk_builder_get_object (builder, "txt_res");
  buffer = (GtkTextBuffer *) gtk_text_view_get_buffer(text_view);

  /*
  gtk_text_buffer_set_text(buffer, "test!", 5);
  button = gtk_builder_get_object (builder, "button2");
  g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);

  button = gtk_builder_get_object (builder, "quit");
  g_signal_connect (button, "clicked", G_CALLBACK (gtk_main_quit), NULL);
  */
  gtk_widget_show(window);

  gtk_main ();

  return 0;
}
